import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig} from 'axios'
import useUserStore from "@/store/modules/user/user.ts";

// 定义通用响应结构
export interface ApiResponse<T> {
    code: number
    data: T
    msg: string
}

// 创建一个 Axios 实例
const axiosInstance: AxiosInstance = axios.create({
    baseURL: '/api',
    timeout: 10000,
})

// 定义请求拦截器
axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig<any>) => {
    // 在发送请求之前做些什么，比如添加 token 头部等
    const userStore = useUserStore()
    if (userStore.token) {
        config.headers.Authorization = userStore.tokenHeader + userStore.token
    }
    return config
}, (error: any) => {
    // 对请求错误做些什么
    return Promise.reject(error)
})

// 定义响应拦截器
axiosInstance.interceptors.response.use((response): ApiResponse<any> | any => {
    // 对响应数据做些什么，比如处理通用响应结构，返回 data 部分
    const apiResponse: ApiResponse<any> = response.data
    // if the custom code is not 20000, it is judged as an error.
    if (apiResponse.code !== 1000_0000) {
        ElNotification({
            title: 'Error',
            message: apiResponse.msg || 'Error',
            type: 'error',
        })
        return Promise.reject(new Error(apiResponse.msg || 'Error'))
    }
    return apiResponse
}, (error: any) => {
    // 对响应错误做些什么
    let message: string = ''
    //http状态码
    const status = error.response.status
    switch (status) {
        case 401:
        case 403:
            message = '无权访问'
            break
        case 404:
            message = '请求地址错误'
            break
        case 500:
            message = '服务器出现问题'
            break
        default:
            message = '网络出现问题'
            break
    }
    ElNotification({
        title: 'Error',
        message: message,
        type: 'error',
    })
    return Promise.reject(error)
})

// 封装 GET 请求
export function get<T>(url: string, params?: any, config?: AxiosRequestConfig<T>): Promise<AxiosResponse<T>> {
    return axiosInstance.get<T>(url, {params, ...config})
}

// 封装 POST 请求
export function post<T>(url: string, data?: any, config?: AxiosRequestConfig<T>): Promise<AxiosResponse<T>> {
    return axiosInstance.post<T>(url, data, config)
}

// 封装 PUT 请求
export function put<T>(url: string, data?: any, config?: AxiosRequestConfig<T>): Promise<AxiosResponse<T>> {
    return axiosInstance.put<T>(url, data, config)
}

// 封装 DELETE 请求
export function del<T>(url: string, config?: AxiosRequestConfig<T>): Promise<AxiosResponse<T>> {
    return axiosInstance.delete<T>(url, config)
}

export const METHOD: object = {
    GET: 'get',
    POST: 'post',
    PUT: 'put',
    DELETE: 'del'
}

export default axiosInstance
